package com.bestcem.xm.ticket.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.ObjectId;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.ticket.constant.Constants;
import com.bestcem.xm.ticket.controller.param.ticket.config.CreateConfigParam;
import com.bestcem.xm.ticket.controller.param.ticket.config.UpdateConfigParam;
import com.bestcem.xm.ticket.controller.param.ticket.config.createParam.FollowConfigParam;
import com.bestcem.xm.ticket.controller.vo.ticket.config.TicketConfigFlowVO;
import com.bestcem.xm.ticket.controller.vo.ticket.config.TicketConfigInfoV3VO;
import com.bestcem.xm.ticket.controller.vo.ticket.config.TicketConfigInfoVO;
import com.bestcem.xm.ticket.dao.TicketConfigDao;
import com.bestcem.xm.ticket.dao.TicketFlowDao;
import com.bestcem.xm.ticket.entity.mongo.TicketFlow;
import com.bestcem.xm.ticket.enums.FlowMatchConditionEnum;
import com.bestcem.xm.ticket.enums.FollowerFilterEnum;
import com.bestcem.xm.ticket.enums.TicketFlowMatchConditionEnum;
import com.bestcem.xm.ticket.enums.TicketFlowStatusEnum;
import com.bestcem.xm.ticket.grpc.client.TicketBaseUserGrpcService;
import com.bestcem.xm.ticket.grpc.client.dto.user.RoleDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.UserDTO;
import com.bestcem.xm.ticket.service.TicketFlowService;
import com.bestcem.xm.ticket.service.convert.TicketFlowMapper;
import com.bestcem.xm.ticket.service.dto.ticket.flow.InsertFlowDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author liheng
 * @version v1.0
 * @date 2021/8/19 10:59
 */
@Slf4j
@Service
public class TicketFlowServiceImpl implements TicketFlowService {

    @Resource
    private TicketConfigDao ticketConfigDao;

    @Resource
    private TicketFlowDao ticketFlowDao;

    @Resource
    private TicketFlowMapper ticketFlowMapper;

    @Resource
    private TicketBaseUserGrpcService ticketBaseUserGrpcService;

    /**
     * 生成空的跟进配置信息给前端使用
     *
     * @return
     */
    private static List<TicketConfigFlowVO.FollowConfig> getEmptyFollowConfig() {
        TicketConfigFlowVO.FollowConfig followConfig = new TicketConfigFlowVO.FollowConfig();
        followConfig.setFollowerEmail("");
        followConfig.setFollowerFilter(1);
        followConfig.setFollowerId("");
        followConfig.setFollowerName("");
        followConfig.setOptions(new ArrayList<>());
        followConfig.setRegion("");
        followConfig.setRoleId("");
        followConfig.setTimeLimit("");
        followConfig.setTitle("");
        ArrayList<TicketConfigFlowVO.FollowConfig> followConfigs = new ArrayList<>(10);
        followConfigs.add(followConfig);
        return followConfigs;
    }

    @Override
    public TicketConfigInfoVO parseTicketFollowConfigData(TicketConfigInfoVO ticketConfigInfoVO) {
        if (!CollectionUtils.isEmpty(ticketConfigInfoVO.getTicketFlows())) {
            List<TicketConfigFlowVO> ticketFlows = ticketConfigInfoVO.getTicketFlows();
            ticketFlows.sort(Comparator.comparing(TicketConfigFlowVO::getPriority));
            ticketConfigInfoVO.setTicketFlows(ticketFlows);

            List<TicketConfigFlowVO.FollowConfig> followConfig = ticketFlows.get(0).getFollowConfigs();
            ticketConfigInfoVO.setFollowConfigs(parseFollowConfigForTicketConfig(followConfig));
        } else {
            ticketConfigInfoVO.setFollowConfigs(TicketFlowServiceImpl.getEmptyFollowConfig());
        }

        return ticketConfigInfoVO;
    }

    @Override
    public TicketConfigInfoV3VO parseTicketFollowConfigDataV3(TicketConfigInfoV3VO ticketConfigInfoVO) {
        if (!CollectionUtils.isEmpty(ticketConfigInfoVO.getTicketFlows())) {
            List<TicketConfigFlowVO> ticketFlows = ticketConfigInfoVO.getTicketFlows();
            ticketFlows.sort(Comparator.comparing(TicketConfigFlowVO::getPriority));
            ticketConfigInfoVO.setTicketFlows(ticketFlows);

            List<TicketConfigFlowVO.FollowConfig> followConfig = ticketFlows.get(0).getFollowConfigs();
            ticketConfigInfoVO.setFollowConfigs(parseFollowConfigForTicketConfig(followConfig));
        } else {
            ticketConfigInfoVO.setFollowConfigs(TicketFlowServiceImpl.getEmptyFollowConfig());
        }

        return ticketConfigInfoVO;
    }

    @Override
    public List<TicketConfigFlowVO.FollowConfig> parseFollowConfigForTicketConfig(List<TicketConfigFlowVO.FollowConfig> followConfigList) {
        if (CollectionUtils.isEmpty(followConfigList)) {
            return getEmptyFollowConfig();

        }
        for (TicketConfigFlowVO.FollowConfig followConfig : followConfigList) {
            String roleId = followConfig.getRoleId();
            if (ObjectId.isValid(roleId)) {
                // 请求user根据roleId获取roleInfo,get_role(roleId)
                RoleDTO role = ticketBaseUserGrpcService.getRole(roleId);
                if (Objects.nonNull(role)) {
                    followConfig.setTitle(role.getTitle());
                } else {
                    followConfig.setTitle(null);
                    followConfig.setRoleId(null);
                }
            } else {
                followConfig.setTitle(null);
                followConfig.setRoleId(null);
            }

            // 兼容之前的老数据，默认为按照层级, 没有则设置默认值
            followConfig.setFollowerFilter(Objects.isNull(followConfig.getFollowerFilter()) ?
                    FollowerFilterEnum.REGION.getIndex() : followConfig.getFollowerFilter());
            followConfig.setFollowerId(ObjectId.isValid(followConfig.getFollowerId()) ?
                    followConfig.getFollowerId() : Constants.BLANK);

            followConfig.setFollowerName(null);
            followConfig.setFollowerEmail(null);
            if (ObjectId.isValid(followConfig.getFollowerId())) {
                // 请求用户获取用户信息，user_get_user(str(follower_id))
                UserDTO user = ticketBaseUserGrpcService.getUser(followConfig.getFollowerId());
                if (Objects.nonNull(user)) {
                    followConfig.setFollowerName(user.getName());
                    followConfig.setFollowerEmail(user.getEmail());
                }
            }
        }

        return followConfigList;
    }

    @Override
    public ServiceResult<List<String>> createTicketFollow(String ticketConfigId, CreateConfigParam param) {
        if (Objects.isNull(param.getFollowConfig())) {
            return ServiceResult.failWithCode(ReqErrorCodeEnum.PARAM_LOST, "缺少必要参数,TicketFollow");
        }

        InsertFlowDTO ticketFlow = new InsertFlowDTO();
        List<TicketFlow.FollowConfig> followConfigs = new ArrayList<>();
        param.getFollowConfig().forEach(o -> {
            followConfigs.add(FollowConfigParam.paramToEntity(o));
        });

        ticketFlow.setFollowConfig(followConfigs);
        ticketFlow.setOrgId(param.getOrgId());
        ticketFlow.setUserId(param.getUserId());
        ticketFlow.setTicketConfigId(ticketConfigId);
        ticketFlow.setPriority(1);
        ticketFlow.setStatus(TicketFlowStatusEnum.ENABLED.getIndex());
        ticketFlow.setMatchCondition(FlowMatchConditionEnum.UNCONDITIONAL.getIndex());
        String ticketFlowId = this.createTicketFlow(ticketFlow);
        return ServiceResult.success(Arrays.asList(ticketFlowId));
    }

    @Override
    public String createTicketFlow(InsertFlowDTO ticketFlow) {
        // 创建工单系统生成字段, 并将工单流程加入到工单配置中
        // 暂不处理，这个是原来python中的有一个todo的，创建工单流程中设置规则ruleList，暂不处理
        List<String> ruleList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(ticketFlow.getRuleList())) {
            ruleList = ticketFlow.getRuleList();
        }
        if (log.isInfoEnabled()) {
            log.info("初始ruleList={}", ruleList);
        }

        List<TicketFlow> ticketflows = ticketFlowDao.findTicketFlowByStatus(ticketFlow.getTicketConfigId(), TicketFlowStatusEnum.DELETED.getIndex());
        // 工单流程序列号, 自增+1
        int flowId = CollUtil.isEmpty(ticketflows) ? 0 : ticketflows.size() + 1;
        ticketFlow.setFlowId(flowId);
        // 获取新建工单流程的优先级, 自增+1 数字越小优先级越高
        ticketFlow.setPriority(flowId);
        ticketFlow.setStatus(TicketFlowStatusEnum.DISABLED.getIndex());

        if (!CollectionUtils.isEmpty(ruleList)) {
            ticketFlow.setMatchCondition(FlowMatchConditionEnum.CUSTOM_ALERT_RULES.getIndex());
        } else if (Objects.nonNull(ticketFlow.getMatchCondition())) {
            // pass
        } else {
            ticketFlow.setMatchCondition(FlowMatchConditionEnum.UNCONDITIONAL.getIndex());
        }

        // 设置默认不需要审核
        ticketFlow.setNeedAudit(Objects.nonNull(ticketFlow.getNeedAudit()) && ticketFlow.getNeedAudit());

        if (log.isInfoEnabled()) {
            log.info("即将创建工单流程---->>>>>{}", ticketFlow);
        }
        TicketFlow entity = ticketFlowMapper.dtoToEntity(ticketFlow);
        entity = ticketFlowDao.saveTicketFlow(entity);
        if (log.isInfoEnabled()) {
            log.info("生成工单id---->>>>>{}", entity.getId());
        }
        // 参数中不会再存在ruleList参数, 需要对ruleList中的deleted属性，但是现在是string类型的liSt，这一步先注释
        // ruleList = [rule for rule in ruleList if not rule.get('deleted')]
//        if (CollUtil.isNotEmpty(ruleList)) {
//            // 过滤未被删除的
//            ruleList = ruleList.stream().filter(o -> !o.getDeleted()).collect(Collectors.toList());
//        }
//        if (log.isInfoEnabled()) {
//            log.info("处理之后的ruleList={}", ruleList);
//        }
        // 去除updateRuleList操作
        // rule_id_list = await update_rules(str(ticketflow_id), ruleList) if ruleList else []
        // logger.info(f'rpc更新之后的rule_id_list={rule_id_list}')

        //  将工单流程id放到工单配置的ticketFlowIds中,先注释掉，后面的逻辑会将结果存到库中
//        TicketConfig ticketConfig = ticketConfigDao.findById(ticketFlow.getTicketConfigId());
//        if (Objects.nonNull(ticketConfig)){
//            List<String> ticketFlowIds = ticketConfig.getTicketFlowIds();
//            if (Objects.isNull(ticketFlowIds)){
//                List<String> newList = new ArrayList<>(10);
//                newList.add(newTicketFlow.getId());
//                ticketConfig.setTicketFlowIds(newList);
//            }else {
//                ticketFlowIds.add(newTicketFlow.getId());
//            }
//        }
//        ticketConfigDao.saveTicketConfig(ticketConfig);
        return entity.getId();
    }

    @Override
    public void updateTicketFlow(String ticketConfigId, UpdateConfigParam param) {
        List<String> ticketFlowList = Optional.ofNullable(param.getTicketFlowIds()).orElse(new ArrayList<>(2));
        TicketFlow ticketFlow = new TicketFlow();
        if (CollUtil.isNotEmpty(ticketFlowList)) {
            String ticketFlowId = ticketFlowList.get(0);
            ticketFlow.setId(ticketFlowId);
        }
        ticketFlow.setStatus(TicketFlowStatusEnum.ENABLED.getIndex());
        ticketFlow.setPriority(1);
        List<TicketFlow.FollowConfig> list = new ArrayList<>();
        param.getFollowConfig().forEach(o -> {
            list.add(FollowConfigParam.paramToEntity(o));
        });
        ticketFlow.setFollowConfig(list);
        ticketFlow.setMatchCondition(TicketFlowMatchConditionEnum.UNCONDITIONAL.getIndex());

        if (Objects.nonNull(ticketFlow.getId())) {
            ticketFlowDao.updateTicketFlow(ticketFlow.getId(), ticketFlow);
        } else {
            ticketFlow.setTicketConfigId(ticketConfigId);
        }
    }
}
